package com.dk.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.dk.entity.*;
import com.dk.feign.emilFeign;
import com.dk.mapper.*;
import com.dk.service.DtContentService;
import com.dk.util.IdWorker;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

@Service
public class DtContentServiceImpl implements DtContentService {
    @Autowired
    private DtContentMapper contentMapper;
    @Resource
    private RedisTemplate redisTemplate;
    @Resource
    private DtItemMapper itemMapper;
    @Resource
    private DtOrderMapper orderMapper;
    @Resource
    private emilFeign emilFeign;
    @Resource
    private DtPayLogMapper payLogMapper;
    @Resource
    private DtContentChargeMapper contentChargeMapper;
    @Resource
    private IdWorker idWorker;
    private Lock lock =  new ReentrantLock();
    @Override
    public List<DtContent> findList() {
        String key = "content";
        if (redisTemplate.hasKey(key)){
            return (List<DtContent>)redisTemplate.opsForList().leftPop(key);
        }else {
            List<DtContent> dtContents = contentMapper.selectList(null);
            redisTemplate.opsForList().leftPush(key,dtContents);
            return dtContents;
        }
    }

    @Override
    public int contentCharge(Integer uid, Integer goodsId) {
        String s1 = uid.toString();
        String s2 = goodsId.toString();
        //用户id和商品id作为key
        String key = s1 + s2;
        //加锁保证该线程并发
        lock.lock();
        try{
            //判断redis中key是否存在
            if (redisTemplate.hasKey(key)){
                //如果不存在 并进行扣费
                System.out.println("商家还有余额，不进行扣费");
                //否则进行扣费
            }else {
                //对key 设置有效时间
                redisTemplate.boundValueOps(key).set(1);
                redisTemplate.expire(key,15, TimeUnit.MINUTES);
                //通过商品goodsId查询商家
                QueryWrapper<DtItem> queryWrapper = new QueryWrapper<>();
                QueryWrapper<DtContentCharge> queryWrapper1 = new QueryWrapper<>();
                queryWrapper.eq("goods_id", goodsId);
                DtItem dtItems = itemMapper.selectOne(queryWrapper);
                //根据查询出来的商家 查询广告扣费表 查出商家对应的金额
                String seller = dtItems.getSeller();
                queryWrapper1.eq("seller", seller);
                DtContentCharge charge1 = contentChargeMapper.selectOne(queryWrapper1);
                DtContentCharge charge = new DtContentCharge();
                String money = charge1.getMoney().toString();
                //如果商家还有余额大于10元 进行扣费，并更新数据库
                //如果商家小于余额10通过发送短信 提醒用户尽快续费，到扣费为0 ，超过半个小时没有续费
                // 通过分布式事物消息mq发送给上架服务 对商品进行下架处理
                if ( Integer.parseInt(money)> 10){
                    int i = Integer.parseInt(money) - 1;
                    charge.setMoney(BigDecimal.valueOf(i));
                    charge.setSeller(seller);
                    charge.setCid(charge1.getCid());
                    contentChargeMapper.updateById(charge);
                }else {
                    emilFeign.update("尽快续约,否则面临下架风险");
                    System.out.println("发送邮件提醒商家续约,否则面临下架风险");
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
        return 0;
    }
    @Override
    public Map contentInsert(DtContent content) {
        Map map = new HashMap();
        //增加广告表
        contentMapper.insert(content);
        //增加订单表
        long id = idWorker.nextId();
        DtOrder order = new DtOrder();
        order.setStatus("1");
        order.setPaymentorderno(String.valueOf(id));
        order.setCreateTime(new Date());
        order.setEndTime(new Date());
        order.setSellerId("1");
        order.setUserId("1");
        order.setPayment(BigDecimal.valueOf(500));
        order.setPaymentType("1");
        orderMapper.insert(order);

        //增加广告收费表
        DtContentCharge charge = new DtContentCharge();
        charge.setMoney(content.getMoney());
        //广告表考虑欠缺没有设置商家名称的字段 先进行写死
        String seller= "京东商店";
        charge.setSeller(seller);
       //通过广告的seller 商家查询 广告收费表是否有该用户
        // 如果有 取出广告费 和新增广告费相加存入数据库中
        //如果广告收费表没有该商家 代表该商家第一次入住 直接插入
        QueryWrapper<DtContentCharge> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("seller",seller);
        DtContentCharge charge1 = contentChargeMapper.selectOne(queryWrapper);
        if (ObjectUtils.isEmpty(charge1)){
            contentChargeMapper.insert(charge);
        }else {
            Integer x = new Integer(String.valueOf(charge1.getMoney()));
            Integer xx = new Integer(String.valueOf(content.getMoney()));
            Integer y = x + xx;
            charge.setMoney(BigDecimal.valueOf(y));
            contentChargeMapper.insert(charge);
        }
        //给前段返回 订单号和金额等
        map.put("money",content.getMoney());
        map.put("title",content.getTitle());
        map.put("trade_out",id);
        return map;
    }
    @Override
    public void updatestatus(String out_trade_no, String trade_no) {
        QueryWrapper<DtOrder> queryWrapper = new QueryWrapper();
        queryWrapper.eq("paymentorderno" , out_trade_no);
        DtOrder dtOrder = new DtOrder();
        dtOrder.setRunningwater(trade_no);
        dtOrder.setStatus("2");
        orderMapper.update(dtOrder,queryWrapper);
    }

    @Override
    public void insertPayLog(String out_trade_no, String total_amount, String trade_no, String s) {
        QueryWrapper<DtOrder> wrapper = new QueryWrapper<>();
        wrapper.eq("paymentorderno", out_trade_no);
        DtOrder dtOrder = orderMapper.selectOne(wrapper);
        DtPayLog dtPayLog = new DtPayLog();
        dtPayLog.setOutTradeNo(out_trade_no);
        dtPayLog.setCreateTime(new Date());
        dtPayLog.setPayTime(new Date());
        dtPayLog.setUserId("1");
        dtPayLog.setTransactionId(trade_no);
        dtPayLog.setOrderList(dtOrder.toString());
        dtPayLog.setTradeState("1");
        dtPayLog.setPayType("1");
        payLogMapper.insert(dtPayLog);
    }
}
